home *** CD-ROM | disk | FTP | other *** search
/ Download Now 8 / Download Now V8.iso / Program / InternetTools / ApacheWebServer1.3.6 / apache_1_3_6_win32.exe / _SETUP.1 / rfc1413.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-01  |  8.2 KB  |  239 lines

  1. /* ====================================================================
  2.  * Copyright (c) 1995-1999 The Apache Group.  All rights reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  *
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer. 
  10.  *
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in
  13.  *    the documentation and/or other materials provided with the
  14.  *    distribution.
  15.  *
  16.  * 3. All advertising materials mentioning features or use of this
  17.  *    software must display the following acknowledgment:
  18.  *    "This product includes software developed by the Apache Group
  19.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  20.  *
  21.  * 4. The names "Apache Server" and "Apache Group" must not be used to
  22.  *    endorse or promote products derived from this software without
  23.  *    prior written permission. For written permission, please contact
  24.  *    apache@apache.org.
  25.  *
  26.  * 5. Products derived from this software may not be called "Apache"
  27.  *    nor may "Apache" appear in their names without prior written
  28.  *    permission of the Apache Group.
  29.  *
  30.  * 6. Redistributions of any form whatsoever must retain the following
  31.  *    acknowledgment:
  32.  *    "This product includes software developed by the Apache Group
  33.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  36.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  37.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  38.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  41.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  43.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  44.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  45.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  46.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Group and was originally based
  51.  * on public domain software written at the National Center for
  52.  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
  53.  * For more information on the Apache Group and the Apache HTTP server
  54.  * project, please see <http://www.apache.org/>.
  55.  *
  56.  */
  57.  
  58. /*
  59.  * rfc1413() speaks a common subset of the RFC 1413, AUTH, TAP and IDENT
  60.  * protocols. The code queries an RFC 1413 etc. compatible daemon on a remote
  61.  * host to look up the owner of a connection. The information should not be
  62.  * used for authentication purposes. This routine intercepts alarm signals.
  63.  * 
  64.  * Diagnostics are reported through syslog(3).
  65.  * 
  66.  * Author: Wietse Venema, Eindhoven University of Technology,
  67.  * The Netherlands.
  68.  */
  69.  
  70. /* Some small additions for Apache --- ditch the "sccsid" var if
  71.  * compiling with gcc (it *has* changed), include ap_config.h for the
  72.  * prototypes it defines on at least one system (SunlOSs) which has
  73.  * them missing from the standard header files, and one minor change
  74.  * below (extra parens around assign "if (foo = bar) ..." to shut up
  75.  * gcc -Wall).
  76.  */
  77.  
  78. /* Rewritten by David Robinson */
  79.  
  80. #include "httpd.h"        /* for server_rec, conn_rec, ap_longjmp, etc. */
  81. #include "http_log.h"        /* for aplog_error */
  82. #include "rfc1413.h"
  83. #include "http_main.h"        /* set_callback_and_alarm */
  84.  
  85. /* Local stuff. */
  86. /* Semi-well-known port */
  87. #define    RFC1413_PORT    113
  88. /* maximum allowed length of userid */
  89. #define RFC1413_USERLEN 512
  90. /* rough limit on the amount of data we accept. */
  91. #define RFC1413_MAXDATA 1000
  92.  
  93. #ifndef RFC1413_TIMEOUT
  94. #define RFC1413_TIMEOUT    30
  95. #endif
  96. #define    ANY_PORT    0    /* Any old port will do */
  97. #define FROM_UNKNOWN  "unknown"
  98.  
  99. int ap_rfc1413_timeout = RFC1413_TIMEOUT;    /* Global so it can be changed */
  100.  
  101. static JMP_BUF timebuf;
  102.  
  103. /* bind_connect - bind both ends of a socket */
  104. /* Ambarish fix this. Very broken */
  105. static int get_rfc1413(int sock, const struct sockaddr_in *our_sin,
  106.                const struct sockaddr_in *rmt_sin, 
  107.                char user[RFC1413_USERLEN+1], server_rec *srv)
  108. {
  109.     struct sockaddr_in rmt_query_sin, our_query_sin;
  110.     unsigned int rmt_port, our_port;
  111.     int i;
  112.     char *cp;
  113.     char buffer[RFC1413_MAXDATA + 1];
  114.     int buflen;
  115.  
  116.     /*
  117.      * Bind the local and remote ends of the query socket to the same
  118.      * IP addresses as the connection under investigation. We go
  119.      * through all this trouble because the local or remote system
  120.      * might have more than one network address. The RFC1413 etc.
  121.      * client sends only port numbers; the server takes the IP
  122.      * addresses from the query socket.
  123.      */
  124.  
  125.     our_query_sin = *our_sin;
  126.     our_query_sin.sin_port = htons(ANY_PORT);
  127.     rmt_query_sin = *rmt_sin;
  128.     rmt_query_sin.sin_port = htons(RFC1413_PORT);
  129.  
  130.     if (bind(sock, (struct sockaddr *) &our_query_sin,
  131.          sizeof(struct sockaddr_in)) < 0) {
  132.     ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
  133.             "bind: rfc1413: Error binding to local port");
  134.     return -1;
  135.     }
  136.  
  137. /*
  138.  * errors from connect usually imply the remote machine doesn't support
  139.  * the service
  140.  */
  141.     if (connect(sock, (struct sockaddr *) &rmt_query_sin,
  142.         sizeof(struct sockaddr_in)) < 0)
  143.                 return -1;
  144.  
  145. /* send the data */
  146.     buflen = ap_snprintf(buffer, sizeof(buffer), "%u,%u\r\n", ntohs(rmt_sin->sin_port),
  147.         ntohs(our_sin->sin_port));
  148.  
  149.     /* send query to server. Handle short write. */
  150.     i = 0;
  151.     while(i < strlen(buffer)) {
  152.         int j;
  153.     j = write(sock, buffer+i, (strlen(buffer+i)));
  154.     if (j < 0 && errno != EINTR) {
  155.       ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
  156.                "write: rfc1413: error sending request");
  157.       return -1;
  158.     }
  159.     else if (j > 0) {
  160.         i+=j; 
  161.     }
  162.     }
  163.  
  164.     /*
  165.      * Read response from server. - the response should be newline 
  166.      * terminated according to rfc - make sure it doesn't stomp it's
  167.      * way out of the buffer.
  168.      */
  169.  
  170.     i = 0;
  171.     memset(buffer, 0, sizeof(buffer));
  172.     while((cp = strchr(buffer, '\n')) == NULL && i < sizeof(buffer) - 1) {
  173.         int j;
  174.     j = read(sock, buffer+i, (sizeof(buffer) - 1) - i);
  175.     if (j < 0 && errno != EINTR) {
  176.        ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
  177.             "read: rfc1413: error reading response");
  178.        return -1;
  179.     }
  180.     else if (j > 0) {
  181.         i+=j; 
  182.     }
  183.     }
  184.  
  185. /* RFC1413_USERLEN = 512 */
  186.     if (sscanf(buffer, "%u , %u : USERID :%*[^:]:%512s", &rmt_port, &our_port,
  187.            user) != 3 || ntohs(rmt_sin->sin_port) != rmt_port
  188.     || ntohs(our_sin->sin_port) != our_port)
  189.     return -1;
  190.  
  191.     /*
  192.      * Strip trailing carriage return. It is part of the
  193.      * protocol, not part of the data.
  194.      */
  195.  
  196.     if ((cp = strchr(user, '\r')))
  197.     *cp = '\0';
  198.  
  199.     return 0;
  200. }
  201.  
  202. /* ident_timeout - handle timeouts */
  203. static void ident_timeout(int sig)
  204. {
  205.     ap_longjmp(timebuf, sig);
  206. }
  207.  
  208. /* rfc1413 - return remote user name, given socket structures */
  209. char *ap_rfc1413(conn_rec *conn, server_rec *srv)
  210. {
  211.     static char user[RFC1413_USERLEN + 1];    /* XXX */
  212.     static char *result;
  213.     static int sock;
  214.  
  215.     result = FROM_UNKNOWN;
  216.  
  217.     sock = ap_psocket(conn->pool, AF_INET, SOCK_STREAM, IPPROTO_TCP);
  218.     if (sock < 0) {
  219.     ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
  220.             "socket: rfc1413: error creating socket");
  221.     conn->remote_logname = result;
  222.     }
  223.  
  224.     /*
  225.      * Set up a timer so we won't get stuck while waiting for the server.
  226.      */
  227.     if (ap_setjmp(timebuf) == 0) {
  228.     ap_set_callback_and_alarm(ident_timeout, ap_rfc1413_timeout);
  229.  
  230.     if (get_rfc1413(sock, &conn->local_addr, &conn->remote_addr, user, srv) >= 0)
  231.         result = user;
  232.     }
  233.     ap_set_callback_and_alarm(NULL, 0);
  234.     ap_pclosesocket(conn->pool, sock);
  235.     conn->remote_logname = result;
  236.  
  237.     return conn->remote_logname;
  238. }
  239.